package com.hexacta.hrs.web.struts.actions;

import java.util.Collection;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.vectrics.employee.Employee;

import com.hexacta.hrs.domain.staffing.Project;
import com.hexacta.hrs.service.staffing.ProjectService;
import com.hexacta.hrs.services.crud.CrudService;
import com.hexacta.hrs.services.employee.EmployeeService;
import com.hexacta.hrs.services.timeoff.CompensationDaysService;
import com.hexacta.hrs.timeoff.CompensationDaysAssignation;

/**
 * 
 * Action de Struts para {@link CompensationDaysAssignation}.
 * 
 * @author mfunes
 * 
 */
public final class CompensationDaysAction extends CrudAbstractAction<CompensationDaysAssignation> {

    private static final long serialVersionUID = 2458931116623003779L;

    private CompensationDaysService compensationDaysService;

    private EmployeeService employeeService;

    private ProjectService projectService;

    private String selectedEmployeeId;

    private Collection<Employee> employeeList;

    private Collection<Project> projectList;

    private String selectedProject;

    private String selectedEmployeeName;

    private String selectedAssignedToId;

    private String selectedAssignedById;

    private String selectedAssignedByName;

    private String selectedQuantity;

    private Date selectedDateFrom;

    private Date selectedDateTo;

    /**
     * @return the selectedDateFrom
     */
    public Date getSelectedDateFrom() {
        return selectedDateFrom;
    }

    /**
     * @param selectedDateFrom
     *            the selectedDateFrom to set
     */
    public void setSelectedDateFrom(final Date selectedDateFrom) {
        this.selectedDateFrom = selectedDateFrom;
    }

    /**
     * @return the selectedDateTo
     */
    public Date getSelectedDateTo() {
        return selectedDateTo;
    }

    /**
     * @param selectedDateTo
     *            the selectedDateTo to set
     */
    public void setSelectedDateTo(final Date selectedDateTo) {
        this.selectedDateTo = selectedDateTo;
    }

    @Override
    protected CrudService<CompensationDaysAssignation> getCrudService() {
        return compensationDaysService;
    }

    public void setCompensationDaysService(final CompensationDaysService compensationDaysService) {
        this.compensationDaysService = compensationDaysService;
    }

    public void setSelectedEmployeeId(final String selectedEmployeeId) {
        this.selectedEmployeeId = selectedEmployeeId;
    }

    public String getSelectedEmployeeId() {
        return selectedEmployeeId;
    }

    public void setSelectedEmployeeName(final String selectedEmployeeName) {
        this.selectedEmployeeName = selectedEmployeeName;
    }

    public String getSelectedEmployeeName() {
        return selectedEmployeeName;
    }

    public void setEmployeeService(final EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    public void setProjectService(final ProjectService projectService) {
        this.projectService = projectService;
    }

    public Collection<Employee> getEmployeeList() {
        employeeList = employeeService.getAll();

        // Si no es el list, saco los no longer employees!
        if (!getActionMethod().equals("CompensationDaysAction_list")) {
            employeeList.removeAll(employeeService.getNoLongerEmployees());
        }

        return employeeList;
    }

    public Collection<Project> getProjectList() {
        projectList = projectService.findAll();

        return projectList;
    }

    public void setEmployeeList(final Collection<Employee> employeeList) {
        this.employeeList = employeeList;
    }

    public void setProjectList(final Collection<Project> projectList) {
        this.projectList = projectList;
    }

    public void setSelectedProject(final String selectedProject) {
        this.selectedProject = selectedProject;
    }

    public void setSelectedAssignedToId(final String selectedAssignedToId) {
        this.selectedAssignedToId = selectedAssignedToId;
    }

    public String getSelectedAssignedToId() {
        return selectedAssignedToId;
    }

    public void setSelectedAssignedById(final String selectedAssignedById) {
        this.selectedAssignedById = selectedAssignedById;
    }

    public String getSelectedAssignedById() {
        return selectedAssignedById;
    }

    public String getSelectedAssignedByName() {
        return selectedAssignedByName;
    }

    public void setSelectedAssignedByName(final String selectedAssignedByName) {
        this.selectedAssignedByName = selectedAssignedByName;
    }

    public String getSelectedQuantity() {
        return selectedQuantity;
    }

    public void setSelectedQuantity(final String selectedQuantity) {
        this.selectedQuantity = selectedQuantity;
    }

    @Override
    public void doActionsBeforeSave() {

        if (getModel().getAssignedBy() == null && getModel().getAssignedTo() == null) {
            getModel().setAssignedBy(
                    employeeService.searchById(NumberUtils.toLong(selectedAssignedById, Long.MIN_VALUE)));
            getModel().setAssignedTo(
                    employeeService.searchById(NumberUtils.toLong(selectedAssignedToId, Long.MIN_VALUE)));
        }
        if (!getSelectedQuantity().isEmpty()) {
            getModel().setQuantity(Integer.parseInt(getSelectedQuantity()));
        }
    }

    @Override
    protected void doActionsAfterSave() {
        selectedEmployeeName = getModel().getAssignedTo().getPerson().getFullName();
        selectedEmployeeId = getModel().getAssignedTo().getPerson().getId().toString();
        selectedAssignedByName = getModel().getAssignedBy().getPerson().getFullName();
        selectedAssignedById = getModel().getAssignedBy().getPerson().getId().toString();
        selectedProject = "";
    }

    @Override
    protected CompensationDaysAssignation getSearchCriteria() {
        CompensationDaysAssignation criteria = new CompensationDaysAssignation();
        if (!StringUtils.isEmpty(selectedProject)) {
            criteria.setProject(selectedProject);
        }
        // If the return value is Long.MIN_VALUE the number could not be parsed.
        if (!StringUtils.isEmpty(selectedEmployeeName)) {
            long id = NumberUtils.toLong(selectedEmployeeId, Long.MIN_VALUE);
            if (Long.MIN_VALUE != id) {
                criteria.setAssignedTo(employeeService.searchById(id));
            } else {
                // Para que no traiga nada
                criteria.setAssignedTo(new Employee());
            }
        }

        if (!StringUtils.isEmpty(selectedAssignedByName)) {
            long byid = NumberUtils.toLong(selectedAssignedById, Long.MIN_VALUE);
            if (Long.MIN_VALUE != byid) {
                criteria.setAssignedBy(employeeService.searchById(byid));
            } else {
                // Para que no traiga nada
                criteria.setAssignedBy(new Employee());
            }
        }

        if (selectedDateFrom != null && selectedDateTo != null) {
            Long aux = selectedDateTo.getTime();
            criteria.setNotes(aux.toString());
            criteria.setDateAssigned(selectedDateFrom);
        }

        return criteria;
    }

    @Override
    public void validate() {
        if (StringUtils.isEmpty(selectedAssignedToId) || !StringUtils.isNumeric(selectedAssignedToId)) {
            addFieldError("assignedTo", "Employee is required");
        }
        if (StringUtils.isEmpty(getModel().getProject())) {
            addFieldError("projecto", "Project is required");
        }
        if (StringUtils.isEmpty(getSelectedQuantity())) {
            addFieldError("days", "Days is required");
        } else {
            if (!getSelectedQuantity().matches("^\\d*$")) {
                addFieldError("days", "Days must be a number");
            }
            if (getSelectedQuantity().matches("^0$")) {
                addFieldError("days", "Days must be greater than 0");
            }
            int maxIntSize = String.valueOf(Integer.MAX_VALUE).length();
            if (getSelectedQuantity().length() > maxIntSize) {
                addFieldError("days", "Days must be smaller than " + (Math.pow(10, maxIntSize) - 1));
            }
        }
        if (StringUtils.isEmpty(selectedAssignedById) || !StringUtils.isNumeric(selectedAssignedById)) {
            addFieldError("assignedBy", "AssignedBy is required");
        }
        if (!getModel().getNotes().isEmpty() && getModel().getNotes().length() > 500) {
            addFieldError("notes", "Notes must have at least 1 character and a top of 500");
        }
    }

}
